home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Library
/
RoseWare - Network Support Library.iso
/
apidev
/
ndr2.exe
/
PRTFILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-02
|
8KB
|
306 lines
/****************************************************************************
The following code was taken from the Network Developer's Resource, published
by RoseWare. All contents are Copyright (c) 1993, RoseWare. All Rights
Reserved.
This material is made available as a service for subscribers of the Network
Developer's Resource. This material is not public domain. Simply put, if you
are not a subscriber of the Network Developer's Resource, you are using this
material illegally.
Those interested in subscribing should contact RoseWare via:
CompuServe: 76711,110
Internet: 76711.110@compuserve.com
Phone: (703) 799-2509
Fax: (703) 799-8041
BBS: (703) 799-2536
US Mail: P.O. Box 257
Mount Vernon, VA 22121-0257
Also see the file SUBSCRIB.TXT in this ZIP file...
Contents:
Excerpts from the Questions and Answers section in the September/October '93
issue of the Network Developer's Resource. See text for explanation of the
code.
****************************************************************************/
// PrtFile -- Prints a file to a NetWare print queue
#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <alloc.h>
#include <stdlib.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long LONG;
#define QUEUE 0x0300
// MAX_BYTES is approximately what's left on the local heap to use as
// a buffer for file i/o
#define MAX_BYTES 63000
// Global types
struct scanBindReq
{
WORD Length;
BYTE Function;
LONG LastObjectID;
WORD ObjectType;
BYTE ObjectNameLength;
BYTE ObjectName[48];
};
struct scanBindRep
{
WORD Length;
LONG ObjectID;
WORD ObjectType;
BYTE ObjectName[48];
BYTE ObjectFlag;
BYTE ObjectSecurity;
BYTE ObjectHasProperties;
};
// Local Prototypes
int ScanBinderyObject( struct scanBindReq *Request, struct scanBindRep *Reply );
int CreateQueueJobAndFile( LONG QueueID, WORD *jobNumber );
int CloseFileAndStartQueueJob( LONG QueueID, WORD jobNumber );
LONG LongSwap( LONG num );
int IntSwap( int num );
void main( int argc, char *argv[] );
void main( int argc, char *argv[] )
{
struct scanBindReq ScanBindRequest;
struct scanBindRep ScanBindReply;
int result, deviceHandle, fileHandle;
unsigned int bytesRead;
WORD jobNumber;
LONG QueueID;
char *buf;
// Check command-line syntax
if ( argc < 3 )
{
printf("usage: PrtFile queueName fileName\n" );
exit( 1 );
}
/* ------------------------------------------------------------- */
/* Step 1: Locate Queue and get it's object ID
/* ------------------------------------------------------------- */
/* Initialize Request/Reply packets to 0 */
memset( &ScanBindRequest, NULL, sizeof( struct scanBindReq ) );
memset( &ScanBindReply, NULL, sizeof( struct scanBindRep ) );
/* Setup for call to scan bindery for our queue */
ScanBindRequest.LastObjectID = 0xFFFFFFFFL;
ScanBindRequest.ObjectType = QUEUE;
strcpy( ScanBindRequest.ObjectName, strupr( argv[1] ) );
ScanBindRequest.ObjectNameLength = strlen( ScanBindRequest.ObjectName );
result = ScanBinderyObject( &ScanBindRequest, &ScanBindReply );
if ( result == 0xFC )
{
printf( "Queue %s not found\n", argv[1] );
exit( 1 );
}
else
{
if ( result )
{
printf( "Error scanning for queue, result = %X\n", result );
exit( 1 );
}
else
QueueID = ScanBindReply.ObjectID;
}
/* ------------------------------------------------------------- */
/* Step 2: Place job into queue with CreateQueueJobAndFile, */
/* open the NETQ device and specified file and */
/* copy the file to NETQ, then close the device */
/* and file and call CloseFileAndStartQueueJob */
/* ------------------------------------------------------------- */
result = CreateQueueJobAndFile( QueueID, &jobNumber );
if ( result )
{
printf( "Error creating queue job and file, result = %X\n", result );
exit( 1 );
}
// Open user-specified file
fileHandle = open( strupr( argv[2] ), O_RDONLY | O_BINARY );
if ( fileHandle == -1 )
{
printf( "Error opening file %s\n", argv[2] );
exit( 1 );
}
// Open NETQ: device
deviceHandle = open( "NETQ", O_WRONLY | O_BINARY );
if ( deviceHandle == -1 )
{
printf( "Error opening device NETQ:\n" );
close( fileHandle );
exit( 1 );
}
buf = (char *)malloc( MAX_BYTES );
bytesRead = MAX_BYTES;
while ( bytesRead == MAX_BYTES )
{
bytesRead = read( fileHandle, buf, MAX_BYTES );
write( deviceHandle, buf, bytesRead );
}
close( fileHandle );
close( deviceHandle );
result = CloseFileAndStartQueueJob( QueueID, jobNumber );
if ( result )
{
printf( "Error closing queue job and file, result = %X\n", result );
exit( 1 );
}
}
int ScanBinderyObject( struct scanBindReq *Request, struct scanBindRep *Reply )
{
Request->Function = 0x37;
Request->Length = sizeof( struct scanBindReq ) - 2;
Reply->Length = sizeof( struct scanBindRep ) - 2;
_SI = (unsigned)Request;
_DI = (unsigned)Reply;
_ES = _DS;
_AH = 0xE3;
geninterrupt( 0x21 );
return _AL;
}
int CreateQueueJobAndFile( LONG QueueID, WORD *jobNumber )
{
int result;
struct createQueueJobReq
{
WORD Length;
BYTE Function;
LONG QueueID;
BYTE ClientStation;
BYTE ClientTaskNumber;
LONG ClientIDNumber;
LONG TargetServerIDNumber;
BYTE TargetExecutionTime[6];
BYTE JobEntryTime[6];
WORD JobNumber;
WORD JobType;
BYTE JobPosition;
BYTE JobControlFlags;
BYTE JobFileName[14];
BYTE JobFileHandle[6];
BYTE ServerStation;
BYTE ServerTaskNumber;
LONG ServerIDNumber;
BYTE TextJobDescription[50];
BYTE ClientRecordArea[152];
} Request;
struct createQueueJobRep
{
WORD Length;
BYTE ClientStation;
BYTE ClientTaskNumber;
LONG ClientIDNumber;
LONG TargetServerIDNumber;
BYTE TargetExecutionTime[6];
BYTE JobEntryTime[6];
WORD JobNumber;
WORD JobType;
BYTE JobPosition;
BYTE JobControlFlags;
BYTE JobFileName[14];
BYTE JobFileHandle[6];
BYTE ServerStation;
BYTE ServerTaskNumber;
LONG ServerIDNumber;
} Reply;
/* Initialize Request/Reply packets to 0 */
memset( &Request, NULL, sizeof( Request ) );
memset( &Reply, NULL, sizeof( Reply ) );
Request.Length = sizeof( Request ) - 2;
Request.Function = 0x68; /* Monumental confusion, Novell manual says 6D */
Request.QueueID = QueueID;
Request.TargetServerIDNumber = 0xFFFFFFFF;
memset( Request.TargetExecutionTime, 0xFF, 6 );
Reply.Length = sizeof( Reply ) - 2;
_SI = (unsigned)&Request;
_DI = (unsigned)&Reply;
_ES = _DS;
_AH = 0xE3;
geninterrupt( 0x21 );
result = _AL;
*jobNumber = Reply.JobNumber;
return result;
}
int CloseFileAndStartQueueJob( LONG QueueID, WORD jobNumber )
{
BYTE Request[9] = { 9, 0, 0x69, 0, 0, 0, 0, 0, 0 };
WORD Reply = 0;
*( (LONG *) ( Request + 3 ) ) = QueueID;
*( (WORD *) ( Request + 7 ) ) = jobNumber;
_SI = (unsigned)Request;
_DI = (unsigned)&Reply;
_ES = _DS;
_AH = 0xE3;
geninterrupt( 0x21 );
return _AL;
}
LONG LongSwap( LONG num )
{
LONG temp;
temp = ( num & 0xFF000000 ) >> 24;
temp += ( num & 0xFF0000 ) >> 8;
temp += ( num & 0xFF00 ) << 8;
temp += ( num & 0xFF ) << 24;
return temp;
}
int IntSwap( int num )
{
int temp;
temp = ( num & 0xFF00 ) >> 8;
temp += ( num & 0xFF ) << 8;
return temp;
}